﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace VisualisationModule.View
{

    public partial class VisualisationArea : UserControl
    {
        public VisualisationArea()
        {
            InitializeComponent();
            VisualisationScroller.PreviewMouseWheel += OnPreviewMouseWheel;
            CustomDrawingElement.MouseMove += OnMouseMove;
            CustomDrawingElement.MouseLeftButtonDown += OnMouseLeftButtonDown;
            CustomDrawingElement.MouseLeftButtonUp += OnMouseLeftButtonUp;
            CustomDrawingElement.MouseEnter += OnMouseEntered;
            CustomDrawingElement.MouseLeave += OnMouseLeft;
        }

        private void OnMouseLeft(object sender, MouseEventArgs e)
        {
            Cursor = Cursors.Arrow;
        }

        private void OnMouseEntered(object sender, MouseEventArgs e)
        {
            if (_numberDrawnItems != 0)
            {
                Cursor = Cursors.Hand;
            }
            
        }

        private Point _originalDimensions;
        private void VisualisationBox_Loaded(object sender, RoutedEventArgs e)
        {
            var viewBox = sender as Viewbox;
            if (viewBox != null)
            {
                viewBox.Width = viewBox.ActualWidth;
                viewBox.Height = viewBox.ActualHeight;
                _originalDimensions = new Point(viewBox.ActualWidth, viewBox.ActualHeight);
            }
        }

        private int _numberDrawnItems = 0; //used to check if things are drawn onto the screen
        private double _zoomScale = 1.0;

        #region Zoom

        
        void OnPreviewMouseWheel(object sender, MouseWheelEventArgs e)
        {
            if(CustomDrawingElement != null && _numberDrawnItems != CustomDrawingElement.Items.Count) //if there was something draw to screen
            {
                _numberDrawnItems = CustomDrawingElement.Items.Count;
                CustomDrawingElement.RenderTransformOrigin = new Point(0.5, 0.5); //if not set zoom from center
            }
            if (e.Delta > 0)
            {
                if (CustomDrawingElement != null)
                {
                    _zoomScale++; //increase it now that we have zoomed
                    VisualisationBox.Width = _originalDimensions.X * (_zoomScale); //change the dimensions
                    VisualisationBox.Height = _originalDimensions.Y * (_zoomScale);

                    var mousePosition = e.GetPosition(MasterGrid);
                    mousePosition = MasterGrid.TransformToVisual(VisualisationBox).Transform(mousePosition);

                    VisualisationScroller.ScrollToHorizontalOffset(mousePosition.X); //change the scrollers
                    VisualisationScroller.ScrollToVerticalOffset(mousePosition.Y);
                }
            }
            if (e.Delta < 0)
            {
                if(_zoomScale > 1) //stops you from zooming out too much
                {
                    if (CustomDrawingElement != null)
                    {
                        var mousePosition = e.GetPosition(MasterGrid);

                        _zoomScale -= 1; //decrease the zoom
                        VisualisationBox.Width = VisualisationBox.Width - _originalDimensions.X; //change the dimensions
                        VisualisationBox.Height = VisualisationBox.Height - _originalDimensions.Y;
                        mousePosition = MasterGrid.TransformToVisual(VisualisationBox).Transform(mousePosition);
                        mousePosition = new Point(mousePosition.X - _originalDimensions.X, mousePosition.Y - _originalDimensions.Y);

                        VisualisationScroller.ScrollToHorizontalOffset(mousePosition.X);
                        VisualisationScroller.ScrollToVerticalOffset(mousePosition.Y);
                    }                   
                }
            }

            e.Handled = true;
        }

    #endregion //Zooming code

        //Panning code

        private Point _movementOrigin;
        private void OnMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            if (CustomDrawingElement != null && _numberDrawnItems != 0) //if there was something draw to screen
            {
                _movementOrigin = e.GetPosition(VisualisationScroller);
                CustomDrawingElement.CaptureMouse();
                Stream cursorStream =
                    Application.GetResourceStream(new Uri("/VisualisationModule;component/Resources/cursor_grab.cur",
 UriKind.Relative)).Stream;

                Cursor = new Cursor(cursorStream);
            }
        }

        private void OnMouseMove(object sender, MouseEventArgs e)
        {
            if (CustomDrawingElement.IsMouseCaptured && _numberDrawnItems != 0)
            {
                var mousePosition = e.GetPosition(VisualisationScroller); //curent mous pos
                Vector amountMoved = _movementOrigin - mousePosition; //from start to now
                VisualisationScroller.ScrollToHorizontalOffset(VisualisationScroller.HorizontalOffset + amountMoved.X);
                VisualisationScroller.ScrollToVerticalOffset(VisualisationScroller.VerticalOffset + amountMoved.Y);
                _movementOrigin = mousePosition; //if still moving make this the new origin
            }
        }

        private void OnMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            CustomDrawingElement.ReleaseMouseCapture();
            Cursor = Cursors.Hand;
        }

    }
}
